package com.quectel.business.dms.application.access;

import com.quectel.business.dms.device.DeviceBusiness;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.application.dto.ApplicationDto;
import com.quectel.core.module.application.service.ApplicationService;
import com.quectel.core.module.device.dto.DeviceCategoryDto;
import com.quectel.core.module.device.dto.DeviceDto;
import com.quectel.core.module.device.dto.DeviceTypeDto;
import com.quectel.core.module.device.service.DeviceCategoryService;
import com.quectel.core.module.device.service.DeviceService;
import com.quectel.core.module.device.service.DeviceTypeService;
import com.quectel.sys.module.sys.service.SysConfigService;
import com.quectel.util.http.HttpRestUtils;
import com.quectel.util.thread.ThreadPoolUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author yubobo
 * @email bobo.yu@quectel.com
 * @date 2022/1/10 下午2:17
 * 设备接入抽象
 */
public abstract class AbstractApplicationAccessor implements Accessor, DisposableBean {

    @DubboReference
    private DeviceCategoryService deviceCategoryService;
    @DubboReference
    private DeviceTypeService deviceTypeService;
    @DubboReference
    protected DeviceService deviceService;
    @DubboReference
    protected SysConfigService sysConfigService;
    @DubboReference
    protected ApplicationService applicationService;
    @Autowired
    protected DeviceBusiness deviceBusiness;

    private ThreadPoolExecutor threadPool = ThreadPoolUtils.createCommonIOBoundPool("store-device-pool");

    final static protected HttpRestUtils HTTPS_REST_UTILS = HttpRestUtils.getTrustSSLInstance();

    private static final Logger LOGGER = LoggerFactory.getLogger(AbstractApplicationAccessor.class);

    @Override
    public void destroy() throws Exception {
        ThreadPoolUtils.shutdown(threadPool);
    }

    protected void handException(Throwable throwable) {
        LOGGER.error("实现类抛出异常", throwable);
    }

    /**
     * 填充设备类型等关联字段
     *
     * @param unfilledDevice 需要填充的dto
     * @param applicationDto 应用dto
     */
    protected void fill(DeviceDto unfilledDevice, ApplicationDto applicationDto) {
        if (unfilledDevice == null || applicationDto == null) {
            return;
        }
        unfilledDevice.setApplicationId(applicationDto.getId());
        unfilledDevice.setVillageId(applicationDto.getVillageId());
        unfilledDevice.setTenantId(applicationDto.getTenantId());
        unfilledDevice.setParentId(unfilledDevice.getParentId() == null ? Long.valueOf(SystemConstants.NONEXISTENT_ID) : unfilledDevice.getParentId());
        if (unfilledDevice.getOriginName() == null) {
            unfilledDevice.setOriginName(unfilledDevice.getName());
        }
        DeviceTypeDto deviceTypeDto = null;
        if (unfilledDevice.getDeviceTypeId() != null) {
            deviceTypeDto = deviceTypeService.selectCacheById(unfilledDevice.getDeviceTypeId());
        } else {
            String simpleName = getClass().getSimpleName();
            String deviceTypeCode = simpleName.substring(0, simpleName.indexOf("AccessorImpl"));
            deviceTypeDto = deviceTypeService.selectByCode(deviceTypeCode);
        }

        if (deviceTypeDto != null) {
            deviceTypeDto = deviceTypeService.selectCacheById(deviceTypeDto.getId());
            unfilledDevice.setDeviceTypeId(deviceTypeDto.getId());
            unfilledDevice.setDeviceType(deviceTypeDto);

            DeviceCategoryDto deviceCategoryDto = deviceCategoryService.selectById(deviceTypeDto.getDeviceCategoryId());
            unfilledDevice.setDeviceCategoryId(deviceCategoryDto.getId());
            unfilledDevice.setDeviceCategory(deviceCategoryDto);
        }
    }


}